﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKRGeometry;
using TopologySearch;

namespace YJKArchMethodLibrary.ColumnProfileAnalyze
{
	public class ColumnProfileAnalyzer
	{
		public ColumnProfileAnalyzer(ExternalCommandData cmdData)
		{
			this.m_ComdData = cmdData;
			this.m_UIApp = cmdData.Application;
			this.m_Doc = this.m_UIApp.ActiveUIDocument.Document;
		}

		public void GetCurrentLayerColumeInfos(ref List<ColumnProfileInfo> columnProfileLoopList)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_Doc, this.m_Doc.ActiveView.Id);
			foreach (Element column in filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_Columns).ToElements())
			{
				this.GetColumnProfile(column, ref columnProfileLoopList);
			}
			new FilteredElementCollector(this.m_Doc, this.m_Doc.ActiveView.Id);
			foreach (Element column2 in filteredElementCollector.OfClass(typeof(FamilyInstance)).OfCategory(BuiltInCategory.OST_StructuralColumns).ToElements())
			{
				this.GetColumnProfile(column2, ref columnProfileLoopList);
			}
		}

		public List<Pole2D> GetColumnProfile(Element column, ref List<ColumnProfileInfo> columnProfileLoopList)
		{
			List<Pole2D> list = new List<Pole2D>();
			XYZ point = (column.Location as LocationPoint).Point;
			foreach (Solid solid in this.GetElementSolids(column))
			{
				List<Pole2D> solidProfile = this.GetSolidProfile(point, solid, column.Id, ref columnProfileLoopList);
				list.AddRange(solidProfile);
			}
			return list;
		}

		public List<Solid> GetElementSolids(Element element)
		{
			Options options = this.m_UIApp.Application.Create.NewGeometryOptions();
			options.DetailLevel = (ViewDetailLevel)3;
			options.IncludeNonVisibleObjects = true;
			GeometryElement geometryElement;
			if (element.GetType() == typeof(FamilyInstance))
			{
				FamilyInstance familyInstance = element as FamilyInstance;
				geometryElement = familyInstance.GetOriginalGeometry(options);
				geometryElement = geometryElement.GetTransformed(familyInstance.GetTransform());
			}
			else
			{
				geometryElement = element.get_Geometry(options);
			}
			List<Solid> list = new List<Solid>();
			if (null == geometryElement)
			{
				return list;
			}
			foreach (GeometryObject geometryObject in geometryElement)
			{
				if (!(geometryObject.GetType() != typeof(Solid)))
				{
					Solid solid = geometryObject as Solid;
					if (solid != null && !Geometry.LessThan(solid.Volume, 0.001))
					{
						list.Add(solid);
					}
				}
			}
			return list;
		}

		public List<Pole2D> GetSolidProfile(XYZ location, Solid solid, ElementId columnId, ref List<ColumnProfileInfo> columnProfileLoopList)
		{
			List<Pole2D> list = new List<Pole2D>();
			foreach (object obj in solid.Faces)
			{
				Face face = (Face)obj;
				if (!(face.GetType() != typeof(PlanarFace)) && Geometry.IsEqual((face as PlanarFace).FaceNormal(), -XYZ.BasisZ))
				{
					foreach (object obj2 in face.EdgeLoops)
					{
						EdgeArray edgeArray = (EdgeArray)obj2;
						List<XYZ> list2 = new List<XYZ>();
						new List<EdgeInfo>();
						foreach (object obj3 in edgeArray)
						{
							Curve curve = ((Edge)obj3).AsCurve();
							Pole2D item = Pole2D.TransformWallToStructure2DPole(curve, columnId, 0.0, 0.0);
							list.Add(item);
							list2.AddRange(curve.Tessellate());
						}
						ColumnProfileInfo item2 = new ColumnProfileInfo(location, list2);
						columnProfileLoopList.Add(item2);
					}
				}
			}
			return list;
		}

		private ExternalCommandData m_ComdData;

		private UIApplication m_UIApp;

		private Document m_Doc;
	}
}
